﻿Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Drawing.Design
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Compiler
Imports System.Workflow.ComponentModel.Design

Namespace System.Workflow.Activities
    <ActivityValidator(GetType(InvokeWorkflowValidator)), DefaultEvent("Invoking"), ToolboxBitmap(GetType(InvokeWorkflowActivity), "Resources.Service.bmp"), SRDescription("InvokeWorkflowActivityDescription"), ToolboxItem(GetType(ActivityToolboxItem))> _
    Public NotInheritable Class InvokeWorkflowActivity
        Inherits Activity
        Implements ITypeFilterProvider
        ' Events
        <MergableProperty(False), SRDescription("InitializeCaleeDescr"), SRCategory("Handlers")> _
        Public Custom Event Invoking As EventHandler
            AddHandler(ByVal value As EventHandler)
                MyBase.AddHandler(InvokeWorkflowActivity.InvokingEvent, value)
            End AddHandler
            RemoveHandler(ByVal value As EventHandler)
                MyBase.RemoveHandler(InvokeWorkflowActivity.InvokingEvent, value)
            End RemoveHandler
        End Event

        ' Methods
        Public Sub New()
            MyBase.SetReadOnlyPropertyValue(InvokeWorkflowActivity.ParameterBindingsProperty, New WorkflowParameterBindingCollection(Me))
        End Sub

        Public Sub New(ByVal name As String)
            MyBase.New(name)
            MyBase.SetReadOnlyPropertyValue(InvokeWorkflowActivity.ParameterBindingsProperty, New WorkflowParameterBindingCollection(Me))
        End Sub

        Protected Overrides Function Execute(ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            MyBase.RaiseEvent(InvokeWorkflowActivity.InvokingEvent, Me, EventArgs.Empty)
            Dim namedArgumentValues As New Dictionary([Of] String, Object)
            Dim binding As WorkflowParameterBinding
            For Each binding In Me.ParameterBindings
                namedArgumentValues.Add(binding.ParameterName, binding.Value)
            Next
            Dim service As IStartWorkflow = [TryCast](executionContext.GetService(GetType(IStartWorkflow)),IStartWorkflow)
            If (service Is Nothing) Then
                Throw New InvalidOperationException(SR.GetString("General_MissingService", New Object() { GetType(IStartWorkflow).FullName }))
            End If
            Dim guid As Guid = service.StartWorkflow(Me.TargetWorkflow, namedArgumentValues)
            If (guid = Guid.Empty) Then
                Throw New InvalidOperationException(SR.GetString("Error_FailedToStartTheWorkflow"))
            End If
            Me.SetInstanceId(guid)
            Return ActivityExecutionStatus.Closed
        End Function

        Friend Sub SetInstanceId(ByVal value As Guid)
            MyBase.SetValue(InvokeWorkflowActivity.InstanceIdProperty, value)
        End Sub

        Private Function System.Workflow.ComponentModel.Design.ITypeFilterProvider.CanFilterType(ByVal type As Type, ByVal throwOnError As Boolean) As Boolean Implements ITypeFilterProvider.CanFilterType
            If (type Is Nothing) Then
                Throw New ArgumentNullException("type")
            End If
            Dim flag As Boolean = ((TypeProvider.IsAssignable(GetType(Activity), type) AndAlso (Not type Is GetType(Activity))) AndAlso Not type.IsAbstract)
            If flag Then
                Dim service As IDesignerHost = [TryCast](Me.Site.GetService(GetType(IDesignerHost)),IDesignerHost)
                If ((Not service Is Nothing) AndAlso (String.Compare(service.RootComponentClassName, type.FullName, StringComparison.Ordinal) = 0)) Then
                    If throwOnError Then
                        Throw New InvalidOperationException(SR.GetString("Error_CantInvokeSelf"))
                    End If
                    flag = False
                End If
            End If
            If (throwOnError AndAlso Not flag) Then
                Throw New Exception(SR.GetString("Error_TypeIsNotRootActivity", New Object() { "TargetWorkflow" }))
            End If
            Return flag
        End Function


        ' Properties
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property InstanceId As Guid
            Get
                Return DirectCast(MyBase.GetValue(InvokeWorkflowActivity.InstanceIdProperty), Guid)
            End Get
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(False)> _
        Public ReadOnly Property ParameterBindings As WorkflowParameterBindingCollection
            Get
                Return [TryCast](MyBase.GetValue(InvokeWorkflowActivity.ParameterBindingsProperty),WorkflowParameterBindingCollection)
            End Get
        End Property

        Private ReadOnly Property System.Workflow.ComponentModel.Design.ITypeFilterProvider.FilterDescription As String
            Get
                Return SR.GetString("FilterDescription_InvokeWorkflow")
            End Get
        End Property

        <DefaultValue(CStr(Nothing)), SRDescription("TargetWorkflowDescr"), Editor(GetType(TypeBrowserEditor), GetType(UITypeEditor)), SRCategory("Activity")> _
        Public Property TargetWorkflow As Type
            Get
                Return [TryCast](MyBase.GetValue(InvokeWorkflowActivity.TargetWorkflowProperty),Type)
            End Get
            Set(ByVal value As Type)
                MyBase.SetValue(InvokeWorkflowActivity.TargetWorkflowProperty, value)
            End Set
        End Property


        ' Fields
        Public Shared ReadOnly InstanceIdProperty As DependencyProperty = DependencyProperty.Register("InstanceId", GetType(Guid), GetType(InvokeWorkflowActivity), New PropertyMetadata(Guid.Empty))
        Public Shared ReadOnly InvokingEvent As DependencyProperty = DependencyProperty.Register("Invoking", GetType(EventHandler), GetType(InvokeWorkflowActivity))
        Public Shared ReadOnly ParameterBindingsProperty As DependencyProperty = DependencyProperty.Register("ParameterBindings", GetType(WorkflowParameterBindingCollection), GetType(InvokeWorkflowActivity), New PropertyMetadata((DependencyPropertyOptions.Metadata Or DependencyPropertyOptions.ReadOnly), New Attribute() { New BrowsableAttribute(False), New DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content) }))
        Friend Shared ReadOnly ReservedParameterNames As ArrayList = New ArrayList(New String() { "Name", "Enabled", "Description", "TargetWorkflow", "Invoking", "ParameterBindings" })
        Public Shared ReadOnly TargetWorkflowProperty As DependencyProperty = DependencyProperty.Register("TargetWorkflow", GetType(Type), GetType(InvokeWorkflowActivity), New PropertyMetadata(Nothing, DependencyPropertyOptions.Metadata))
    End Class
End Namespace

